package com.graduation.rescuematerial.service.impl;


import com.graduation.rescuematerial.exception.GlobalException;
import com.graduation.rescuematerial.mapper.CompanyMapper;
import com.graduation.rescuematerial.mapper.UserActionMapper;
import com.graduation.rescuematerial.mapper.UserCompanyMapper;
import com.graduation.rescuematerial.mapper.UserMapper;
import com.graduation.rescuematerial.pojo.Company;
import com.graduation.rescuematerial.pojo.User;
import com.graduation.rescuematerial.pojo.UserAction;
import com.graduation.rescuematerial.pojo.UserCompany;
import com.graduation.rescuematerial.service.UserService;
import com.graduation.rescuematerial.utils.CookieUtil;
import com.graduation.rescuematerial.utils.MD5Util;
import com.graduation.rescuematerial.utils.UUIDUtil;
import com.graduation.rescuematerial.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * @Author:ZhaoXinYi
 * @FileName:
 * @Date:Created in  2022/4/12 21:59
 * @Version:
 * @Description:TODO
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserActionMapper userActionMapper;
    @Autowired
    private UserCompanyMapper userCompanyMapper;
    @Autowired
    private CompanyMapper companyMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    JavaMailSenderImpl mailSender;


    /**
     * 根据cookie获取用户
     *
     * @param ticket
     * @param request
     * @param response
     * @return
     */
    @Override
    public UserVo getUserByCookie(String ticket, HttpServletRequest request, HttpServletResponse response) {
        if (StringUtils.isEmpty(ticket)) {
            return null;
        }
        UserVo user = (UserVo) redisTemplate.opsForValue().get("user:" + ticket);
        if (user != null) {
            //重新设置cookie，处于安全考量
            CookieUtil.setCookie(request, response, "userTicket", ticket);
        }
        return user;
    }

    /**
     * 登录（返回用户全部信息，部门和权限）
     *
     * @param loginVo
     * @param request
     * @param response
     * @return
     */
    @Override
    public RespBean doLogin(LoginVo loginVo, HttpServletRequest request, HttpServletResponse response) {
        String phone = loginVo.getPhone();
        String password = loginVo.getPassword();


        //根据用户手机号获取用户
        User user = userMapper.getUserByPhone(phone);

        //不存在该用户
        if (null == user) {
            throw new GlobalException(RespBeanEnum.LOGIN_ERROR_NOT_EXIST);
        } else {
            //判断密码是否正确
            if (!MD5Util.inputPassToDBPass(password, user.getSalt()).equals(user.getPassword())) {
                throw new GlobalException(RespBeanEnum.PASSWORD_ERROR);
            }
            //判断用户是否注销
            if (!user.getStatus()){
                throw new GlobalException(RespBeanEnum.STATUS_USER_ERROR);
            }
        }

        UserVo userVo=userMapper.getUserAllInfoByPhone(phone);
        try{
        //判断是否有权限和部门
        if(null!=userVo){
            if(userVo.getAction().isEmpty()){
                return RespBean.error(RespBeanEnum.NO_OPERATION_PERMISSION,"无权限，请联系部门管理员分配权限");
            }
            if(userVo.getUserStatus().equals(Boolean.FALSE)){
                return RespBean.error(RespBeanEnum.STATUS_USER_ERROR,"用户已注销，请联系部门管理员");
            }
            if(userVo.getCompanyName().isEmpty()){
                return RespBean.error(RespBeanEnum.NOT_JOIN_COMPANY,"未加入任何组织，请联系管理员添加");
            }
            if(userVo.getCompanyStatus().equals(Boolean.FALSE)){
                return RespBean.error(RespBeanEnum.STATUS_COMPANY_ERROR,"组织已注销，不可登录");
            }
        }else{
            throw new GlobalException(RespBeanEnum.LOGIN_ERROR_NOT_EXIST);
        }


        UserAll userAll=new UserAll();
        userAll.setUserVo(userVo);

        //生成cookie
        String ticket = UUIDUtil.uuid();
        //将用户信息存储在redis中

            redisTemplate.opsForValue().set("user:" + ticket, userVo,7, TimeUnit.DAYS);//将用户名和密码存储在redis里
            //将session存储在cookie中
            CookieUtil.setCookie(request, response, "userTicket", ticket);

            userAll.setTicket(ticket);

            //返回用户的全部信息
            return RespBean.success(userAll);
        }catch (Exception e){
            e.printStackTrace();
            throw new GlobalException();
        }
    }

    /**
     * 用户普通注册（同时向部门（普通用户无部门）和权限表插入数据）
     *
     * @param registerVo
     * @return
     */
    @Override
    public RespBean register(RegisterVo registerVo) {
        //首先判断手机号是否被注册过了
        String phone = registerVo.getUserPhone();

        if (userMapper.getUserByPhone(phone) != null) {
            //用户已被注册
            throw new GlobalException(RespBeanEnum.DUPLICATEKEY_ERROR);
        }

        //向用户表里面添加用户
        User user = new User();
        user.setPassword(MD5Util.inputPassToDBPass(registerVo.getPassword(), "1a2b3c4d"));
        user.setPhone(Long.valueOf(registerVo.getUserPhone()));
        user.setSalt("1a2b3c4d");
        user.setEmail(registerVo.getEmail());

        //添加权限关系
        UserAction userAction = new UserAction();
        userAction.setAction("common_member");
        userAction.setPhone(Long.valueOf(phone));


        //添加部门关系(普通用户无部门)
        UserCompany userCompany = new UserCompany();
        userCompany.setPhone(Long.valueOf(phone));


        try {
            if (userMapper.addUser(user) < 1 || userActionMapper.addUserAction(userAction) < 1 || userCompanyMapper.addUserCompany(userCompany) < 1) {
                throw new GlobalException(RespBeanEnum.REGISTER_ERROR);
            }
        } catch (Exception e) {
            throw new GlobalException(RespBeanEnum.BIN_ERROR);
        }
        return RespBean.success("注册成功！");
    }

    /**
     * 发送验证码
     * @param email
     * @return
     */
    @Override
    public RespBean sendEmail(String email,String message) {
        int count = 1;//默认发送一次
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = null;
        String[] codeNum = message.split(",");
        try {
            helper = new MimeMessageHelper(mimeMessage, true);
            while (count-- != 0) {
//                int[] code = new int[3];
//                Random random = new Random();
//                //自动生成验证码
//                for (int i = 0; i < 6; i++) {
//                    int num = random.nextInt(10) + 48;
//                    int uppercase = random.nextInt(26) + 65;
//                    int lowercase = random.nextInt(26) + 97;
//                    code[0] = num;
//                    code[1] = uppercase;
//                    code[2] = lowercase;
//                    codeNum += (char) code[random.nextInt(3)];
//                }
                //标题
                helper.setSubject("欢迎注册应急救援物资管理系统");
                //内容
                helper.setText("您好！感谢支持应急救援物资管理系统。您的登录账号为：" + "<h2>" + codeNum[0] + "</h2>" +"<h2>" + codeNum[1] + "</h2>" + "千万不能告诉别人哦！", true);
                //邮件接收者
                helper.setTo(email);
                //邮件发送者，必须和配置文件里的一样，不然授权码匹配不上
                helper.setFrom("2243157861@qq.com");
                mailSender.send(mimeMessage);
                System.out.println("邮件发送成功！" + (count + 1));
            }
        } catch (MessagingException e) {
            throw new GlobalException(RespBeanEnum.EMAIL_ERROR);
        }
        return RespBean.success();
    }

    /**
     * 测试一下
     * @return
     */
    @Override
    public RespBean test() {

        User user = new User();
        user.setPassword(MD5Util.inputPassToDBPass("123456", "1a2b3c4d"));
        user.setPhone(18080028002L);
        user.setSalt("1a2b3c4d");
        user.setEmail("18090202385@163.com");

        System.out.println("执行插入语句"+userMapper.insert(user));
        return RespBean.success();
    }

    /**
     * 系统管理员注册用户
     * @param userBaseVo
     * @return
     */
    @Override
    public RespBean registerSysAdmin(UserBaseVo userBaseVo) {

        //首先判断手机号是否被注册过了
        String phone = String.valueOf(userBaseVo.getUserPhone());

        if (userMapper.getUserByPhone(phone) != null) {
            //用户已被注册
            throw new GlobalException(RespBeanEnum.DUPLICATEKEY_ERROR);
        }

        //向用户表里面添加用户
        User user = new User();
        user.setPassword(MD5Util.inputPassToDBPass(userBaseVo.getPassword(), "1a2b3c4d"));
        user.setPhone(Long.valueOf(userBaseVo.getUserPhone()));
        user.setSalt("1a2b3c4d");
        user.setEmail(userBaseVo.getUserEmail());

        //添加权限关系
        UserAction userAction = new UserAction();
        userAction.setAction("system_administrator");
        userAction.setPhone(Long.valueOf(phone));


        //添加部门关系(普通用户无部门)
        UserCompany userCompany = new UserCompany();
        userCompany.setPhone(Long.valueOf(phone));


        try {
            if (userMapper.addUser(user) < 1 || userActionMapper.addUserAction(userAction) < 1 || userCompanyMapper.addUserCompany(userCompany) < 1) {
                throw new GlobalException(RespBeanEnum.REGISTER_ERROR);
            }
        } catch (Exception e) {
            throw new GlobalException(RespBeanEnum.BIN_ERROR);
        }
        return RespBean.success("注册成功！");


//        return userMapper.registerSysAdmin(userBaseVo);
    }

    /**
     * 系统管理员注册用户
     * @param registerUserVo
     * @return
     */
    @Override
    public RespBean registerUser(RegisterUserVo registerUserVo) {

        //首先判断手机号是否被注册过了
        String phone = String.valueOf(registerUserVo.getPhone());

        if (userMapper.getUserByPhone(phone) != null) {
            //用户已被注册
            throw new GlobalException(RespBeanEnum.DUPLICATEKEY_ERROR);
        }

        //向用户表里面添加用户
        User user = new User();
        user.setPassword(MD5Util.inputPassToDBPass(registerUserVo.getPassword(), "1a2b3c4d"));
        user.setPhone(Long.valueOf(registerUserVo.getPhone()));
        user.setSalt("1a2b3c4d");
        user.setEmail(registerUserVo.getEmail());
        user.setHead(registerUserVo.getHead());
        user.setName(registerUserVo.getName());
        user.setAddress(registerUserVo.getAddress());
        user.setSex(registerUserVo.getSex());

        //添加权限关系
        UserAction userAction = new UserAction();
        userAction.setAction(registerUserVo.getAction());
        userAction.setPhone(Long.valueOf(phone));



        //添加部门关系(普通用户无部门)
        RegisterUserCompanyVo userCompany = new RegisterUserCompanyVo();
        userCompany.setPhone(Long.valueOf(phone));
        userCompany.setCompanyName(registerUserVo.getCompanyName());

        //校验权限和部门是否匹配
        if(registerUserVo.getAction().equals("system_administrator") && !registerUserVo.getCompanyName().equals("系统管理员组织（root）")){
            return RespBean.error(RespBeanEnum.ERROR,"非系统成员无法添加系统管理员角色");
        }else if(!registerUserVo.getAction().equals("system_administrator") && registerUserVo.getCompanyName().equals("系统管理员组织（root）")){
            return RespBean.error(RespBeanEnum.ERROR,"目前root部门仅可添加管理员角色");
        }

        //判断部门是否存在
        Company company=companyMapper.getCompanyByName(registerUserVo.getCompanyName());
        if(company==null){
            return RespBean.error(RespBeanEnum.COMPANY_NOTFOUND);
        }
        //判断部门是否注销
        if(company.getStatus().equals(Boolean.FALSE)){
            return RespBean.error(RespBeanEnum.STATUS_COMPANY_ERROR);
        }


        try {
            if (userMapper.addUser(user) < 1 || userActionMapper.addUserAction(userAction) < 1 || userCompanyMapper.addOne(userCompany)<1) {
                throw new GlobalException(RespBeanEnum.REGISTER_ERROR);
            }
        } catch (Exception e) {
            throw new GlobalException(RespBeanEnum.BIN_ERROR);
        }
        return RespBean.success("注册成功！");

    }

    @Override
    public RespBean updateUserInfo(UpdatePersonalInfo updatePersonalInfo) {
        if(null!=updatePersonalInfo.getPassword()&&!updatePersonalInfo.getPassword().isEmpty()){
            //输入的密码为空
            updatePersonalInfo.setPassword(MD5Util.inputPassToDBPass(updatePersonalInfo.getPassword(),"1a2b3c4d"));
        }
        int row=userMapper.updateUserInfo(updatePersonalInfo);
        if(row<1){
            return RespBean.error(RespBeanEnum.UPDATE_ERROR,"修改失败");
        }
        return RespBean.success();
    }

    @Override
    public RespBean updateUserInfo(UpdatePersonalInfo updatePersonalInfo, String companyName) {
        if(null!=updatePersonalInfo.getPassword()&&!updatePersonalInfo.getPassword().isEmpty()){
            //输入的密码为空
            updatePersonalInfo.setPassword(MD5Util.inputPassToDBPass(updatePersonalInfo.getPassword(),"1a2b3c4d"));
        }
        int row=0;
        if(companyName.equals("系统管理员组织（root）")){
            //系统管理员可以修改所有成员信息
            row=userMapper.updateUserInfo(updatePersonalInfo);
        }else {
            //组织下可以修改本部门成员信息
            row=userMapper.updateOrgUserInfo(updatePersonalInfo,companyName);
        }
        if(row<1){
            return RespBean.error(RespBeanEnum.UPDATE_ERROR,"修改失败或非本部门成员");
        }
        return RespBean.success();
    }

    @Override
    public RespBean getOrgCommonUserList(String action, String companyName) {
        if(action.equals("system_administrator")){
            return RespBean.success(userMapper.getAllUser());
        }else if(action.equals("organization_administrator")|| action.equals("organization_member")){
            return RespBean.success(userMapper.getOrgUser(companyName));
        }else {
            return RespBean.success(RespBean.error(RespBeanEnum.NO_OPERATION_PERMISSION,"您没有查看权限"));
        }
    }

    @Override
    public RespBean sysUnionQuery(UnionQueryUserVo unionQueryUserVo) {
        return RespBean.success(userMapper.sysUnionQuery(unionQueryUserVo));
    }

    @Override
    public RespBean cancelUser(Long phone, Boolean status, String companyName) {
        if(companyName.equals("系统管理员组织（root）")){
            companyName=null;
        }
        int row=userMapper.cancelUser(phone,status,companyName);
        if(row<1){
            return RespBean.error(RespBeanEnum.UPDATE_ERROR,"注销失败");
        }
        return RespBean.success();
    }

    @Override
    public RespBean getListByCompanyName(String companyName,String action) {
        return RespBean.success(userMapper.getListByCompanyName(companyName,action));
    }


}

